#pragma once
#include<regex>
#include<iostream>
#include<string>
#include<unordered_map>

//http请求的元素：
//请求行：请求方法，查询字符串，资源路径，协议版本，使用正则表达提取，存储到smatch中
//请求头部：键值对
//请求正文

//实现功能：
//重置请求信息
//插入头部字段
//判断是否存在指定头部字段
//获取指定头部字段的值
//插入查询字符串
//判断是否有某个指定的查询字符串
//获取指定的查询字符串
//获取正文长度
//判断是否是短链接
class HttpRequest{
public:
    std::string _method;//请求方法
    std::string _path;//资源路径
    std::unordered_map<std::string, std::string> _params;//查询字符串
    std::string _vision;//协议版本  
    std::smatch _match;//请求行的正则提取
    std::unordered_map<std::string, std::string> _headers;//请求头部
    std::string _body;//请求正文

    HttpRequest()
    :_vision("HTTP/1.1")
    {}

    //重置请求信息
    void Reset()
    {
        _method.clear();
        _path.clear();
        _params.clear();
        _vision = "HTTP/1.1";
        _headers.clear();
        _body.clear();
        std::smatch match;
        _match.swap(match);
    }

    //添加请求头部信息
    void SetHeader(const std::string& key, const std::string& val)
    {
        _headers.insert(std::make_pair(key, val));
        return;
    }
    //查询信息是否存在
    bool HasHeader(const std::string& key) const
    {
        auto it = _headers.find(key);
        if(it != _headers.end())
        {
            return true;
        }
        return false;
    }
    //获取头部信息
    std::string GetHeader(const std::string& key) const
    {
        auto it = _headers.find(key);
        if(it != _headers.end())
        {
            return "";
        }
        return it->second;
    }

    //添加查询字符串信息
    void SetParams(const std::string& key, const std::string& val)
    {
        _params.insert(std::make_pair(key, val));
        return;
    }
    //查询信息是否存在
    bool HasParams(const std::string& key) const
    {
        auto it = _params.find(key);
        if(it != _params.end())
        {
            return true;
        }
        return false;
    }
    //获取查询字符串
    std::string GetParams(const std::string& key) const
    {
        auto it = _params.find(key);
        if(it != _params.end())
        {
            return "";
        }
        return it->second;
    }

    //获取正文长度
    size_t ContentLength() const
    {
        if(HasHeader("Content-Length") == false)
        {
            return 0;
        }
        else
        {
            std::string len = GetHeader("Content-Length");
            return std::stol(len);
        }
    }
    
    //判断是否是短连接
    bool Close() const
    {
        //如果请求头部没有Connection或者Connection:close，就是短连接
        //如果时Connection:keep-alive,就是长连接
        if(HasHeader("Connection") == true && GetHeader("Connection") == "keep-alive")
        {
            return false;
        }
        else
        {
            return true;
        }
    }
};
